"""
模拟Gemini服务

用于测试和演示的模拟Gemini AI服务。
"""

import asyncio
import random
import time
from typing import Dict, List, Any, Optional
from pathlib import Path
import logging

from PIL import Image
import cv2
import numpy as np

from src.core.di import Injectable, Inject, Service


@Service("mock_gemini_service")
class MockGeminiService:
    """
    模拟Gemini AI服务
    
    提供模拟的视频内容分析和分类功能，用于测试和演示。
    """
    
    def __init__(self,
                 config: Dict[str, Any] = Inject("config"),
                 logger: logging.Logger = Inject("logger")):
        self.config = config
        self.logger = logger
        
        # 模拟配置
        self.model_name = "mock-gemini-2.5-flash"
        self.request_history = []
        
        # 预定义的分类结果模板
        self.classification_templates = {
            "tiktok": {
                "category": "promotional",
                "confidence": 0.85,
                "reasoning": "检测到TikTok风格的短视频内容，包含快节奏剪辑和社交媒体特征",
                "features": ["短视频", "社交媒体", "快节奏", "移动端优化"]
            },
            "product": {
                "category": "product_display",
                "confidence": 0.78,
                "reasoning": "视频主要展示产品特征，包含产品特写和展示角度",
                "features": ["产品展示", "特写镜头", "展示角度", "产品特征"]
            },
            "usage": {
                "category": "product_usage",
                "confidence": 0.82,
                "reasoning": "视频演示产品使用方法和应用场景",
                "features": ["使用演示", "操作指导", "应用场景", "教程内容"]
            },
            "model": {
                "category": "model_wearing",
                "confidence": 0.75,
                "reasoning": "视频包含模特试穿或展示产品的场景",
                "features": ["模特展示", "试穿效果", "人物出镜", "展示场景"]
            },
            "default": {
                "category": "unclassified",
                "confidence": 0.45,
                "reasoning": "无法明确识别视频的主要内容类型",
                "features": ["混合内容", "不明确类型"]
            }
        }
    
    def is_available(self) -> bool:
        """检查服务是否可用"""
        return True
    
    async def extract_video_frames(self, video_path: str, max_frames: int = 5) -> List[Image.Image]:
        """从视频中提取关键帧"""
        try:
            cap = cv2.VideoCapture(video_path)
            if not cap.isOpened():
                raise RuntimeError(f"无法打开视频文件: {video_path}")
            
            # 获取视频信息
            total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
            fps = cap.get(cv2.CAP_PROP_FPS)
            duration = total_frames / fps if fps > 0 else 0
            
            self.logger.debug(f"视频信息: {total_frames}帧, {fps:.2f}FPS, {duration:.2f}秒")
            
            # 计算采样间隔
            if total_frames <= max_frames:
                frame_indices = list(range(total_frames))
            else:
                step = total_frames // max_frames
                frame_indices = [i * step for i in range(max_frames)]
            
            frames = []
            for frame_idx in frame_indices:
                cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx)
                ret, frame = cap.read()
                
                if ret:
                    # 转换BGR到RGB
                    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    
                    # 调整大小
                    height, width = frame_rgb.shape[:2]
                    if width > 1024:
                        scale = 1024 / width
                        new_width = 1024
                        new_height = int(height * scale)
                        frame_rgb = cv2.resize(frame_rgb, (new_width, new_height))
                    
                    # 转换为PIL Image
                    pil_image = Image.fromarray(frame_rgb)
                    frames.append(pil_image)
            
            cap.release()
            
            self.logger.info(f"从视频 {Path(video_path).name} 提取了 {len(frames)} 帧")
            return frames
            
        except Exception as e:
            self.logger.error(f"提取视频帧失败 {video_path}: {e}")
            raise
    
    async def analyze_video(self, video_path: str, prompt: str = None, **kwargs) -> Dict[str, Any]:
        """
        模拟视频分析（兼容接口）

        Args:
            video_path: 视频文件路径
            prompt: 分析提示词
            **kwargs: 其他参数（如categories等）

        Returns:
            分析结果字典
        """
        return await self.analyze_video_content(video_path, **kwargs)

    async def analyze_video_content(self, video_path: str, **kwargs) -> Dict[str, Any]:
        """模拟分析视频内容"""
        try:
            # 模拟处理时间
            await asyncio.sleep(random.uniform(0.5, 1.5))
            
            # 提取视频帧（用于验证视频可访问性）
            max_frames = kwargs.get("max_frames", 5)
            frames = await self.extract_video_frames(video_path, max_frames)
            
            if not frames:
                return {
                    "success": False,
                    "error": "无法提取视频帧",
                    "category": "unclassified",
                    "confidence": 0.0
                }
            
            # 根据文件名选择分类模板
            filename = Path(video_path).name.lower()
            
            if "tiktok" in filename:
                template = self.classification_templates["tiktok"]
            elif "product" in filename:
                template = self.classification_templates["product"]
            elif "usage" in filename or "demo" in filename:
                template = self.classification_templates["usage"]
            elif "model" in filename or "wear" in filename:
                template = self.classification_templates["model"]
            else:
                template = self.classification_templates["default"]
            
            # 添加一些随机性
            confidence_variation = random.uniform(-0.1, 0.1)
            confidence = max(0.0, min(1.0, template["confidence"] + confidence_variation))
            
            # 记录请求
            self.request_history.append(time.time())
            
            result = {
                "success": True,
                "category": template["category"],
                "confidence": confidence,
                "reasoning": template["reasoning"],
                "features": template["features"].copy(),
                "frames_analyzed": len(frames),
                "raw_response": f"模拟AI分析结果: {template['category']} (置信度: {confidence:.2f})"
            }
            
            self.logger.info(f"模拟AI分析完成: {Path(video_path).name} -> {result['category']}")
            
            return result
            
        except Exception as e:
            self.logger.error(f"模拟视频内容分析失败 {video_path}: {e}")
            return {
                "success": False,
                "error": str(e),
                "category": "unclassified",
                "confidence": 0.0
            }
    
    async def batch_analyze_videos(self, video_paths: List[str], **kwargs) -> Dict[str, Dict[str, Any]]:
        """批量分析视频"""
        self.logger.info(f"开始模拟批量分析 {len(video_paths)} 个视频")
        
        results = {}
        
        # 控制并发数
        max_concurrent = kwargs.get("max_concurrent", 3)
        semaphore = asyncio.Semaphore(max_concurrent)
        
        async def analyze_single(video_path: str):
            async with semaphore:
                try:
                    result = await self.analyze_video_content(video_path, **kwargs)
                    return video_path, result
                except Exception as e:
                    self.logger.error(f"模拟分析视频失败 {video_path}: {e}")
                    return video_path, {
                        "success": False,
                        "error": str(e),
                        "category": "unclassified",
                        "confidence": 0.0
                    }
        
        # 创建并发任务
        tasks = [analyze_single(video_path) for video_path in video_paths]
        
        # 等待所有任务完成
        completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
        
        # 处理结果
        for task_result in completed_tasks:
            if isinstance(task_result, Exception):
                self.logger.error(f"模拟批量分析任务失败: {task_result}")
            else:
                video_path, result = task_result
                results[video_path] = result
        
        success_count = len([r for r in results.values() if r.get("success", False)])
        self.logger.info(f"模拟批量分析完成: 成功 {success_count}/{len(video_paths)}")
        
        return results
    
    async def _check_rate_limit(self) -> bool:
        """模拟检查速率限制"""
        # 模拟速率限制检查，总是返回True
        return True
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取模拟服务统计信息"""
        return {
            "total_requests": len(self.request_history),
            "service_type": "mock",
            "model_name": self.model_name,
            "available_templates": list(self.classification_templates.keys()),
            "uptime": "模拟服务始终可用"
        }
